package org.chronologger.poppaea.client;

import java.util.ArrayList;
import java.util.Iterator;

import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.Widget;

/**
 * Provides a cache of reusable widgets
 * 
 * @author johannes
 * 
 * @param <E>
 *            the widget class
 */
public class WidgetCache<E extends Widget> implements Iterable<E> {

	public static interface WidgetFactory<E extends Widget> {
		
		public E make();
		
	}
	
	private static final long serialVersionUID = 1L;

	protected ArrayList<E> widgets = new ArrayList<E>();
	protected WidgetFactory<E> widgetFactory;
	protected HasWidgets parent;
	protected String style;

	/**
	 * Construct a WidgetCache for a given widget class, default parent widget
	 * and css style name
	 * 
	 * @param aClass
	 *            the widget class's class object
	 * @param parent
	 *            a parent widget (can be null)
	 * @param style
	 *            the default css style name
	 */
	public WidgetCache(WidgetFactory<E> factory, HasWidgets parent, String style) {
		this.widgetFactory = factory;
		this.parent = parent;
		this.style = style;
	}

	/**
	 * Sets the number of widgets in this cache. Widgets are automatically
	 * removed from their parent widget. If parent is != null, new widgets
	 * are automatically added to it.
	 * 
	 * @param capacity requested number of widgets
	 */
	public void setCapacity(int capacity) {
		while(widgets.size() > capacity) {
			widgets.get(capacity).removeFromParent();
			widgets.remove(capacity);
		}
		for (int i = widgets.size(); i < capacity; i++) {
			E newWidget = widgetFactory.make();
			newWidget.setStyleName(style);
			if (parent != null)
				parent.add(newWidget);
			widgets.add(newWidget);
		}
	}

	/**
	 * returns the current number of widgets in this cache.
	 * 
	 * @return
	 */
	public int getCapacity() {
		return widgets.size();
	}

	/**
	 * Returns a widget
	 * 
	 * @param index
	 * @return
	 */
	public E get(int index) {
		return widgets.get(index);
	}

	public Iterator<E> iterator() {
		return widgets.iterator();
	}

}
